# -*- coding: utf-8 -*-
#
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

"""MC 扩展处理器

提供 MC 日志函数的装饰器和扩展处理功能。
"""

from typing import cast
from mcpy.ir import IRContext, IRConstant, IRCall
from mcpy.extension_base import extension_processor

LOG_FUNCS = {
    "tlog": True,
    "dlog": True,
    "ilog": True,
    "nlog": True,
    "wlog": True,
    "elog": True,
    "flog": True,
}


def generate_log_code(node: IRCall, function_name: str) -> str:
    from mcpy.codegen.core.generator import get_global_generator
    from mcpy.codegen.core.context import CodeGenContext

    if not node.args:
        return ""

    context = CodeGenContext(current_node=node)
    generator = get_global_generator()

    # 第一个参数是消息模板
    first_arg = node.args[0]

    # 检查是否是常量节点
    if isinstance(first_arg, IRConstant):
        format_str = f'"{first_arg.value}"'
    else:
        # 动态消息字符串表达式
        format_str = generator.generate_expression(
            first_arg, context, parent_precedence=100
        )

    args = [format_str]

    # 处理其他位置参数 - 直接作为位置参数传递
    for i in range(1, len(node.args)):
        arg = node.args[i]
        arg_code = generator.generate_expression(arg, context, parent_precedence=100)
        # 位置参数直接传递，不需要键值对格式
        args.append(arg_code)

    # 处理关键字参数 - 使用键值对格式
    if hasattr(node, "keywords") and node.keywords:
        for kw_tuple in node.keywords:
            # node.keywords 是 tuple 列表：[(key, value), ...]
            if isinstance(kw_tuple, tuple) and len(kw_tuple) == 2:
                kw_name, kw_value = kw_tuple
                arg_code = generator.generate_expression(
                    kw_value, context, parent_precedence=100
                )
                # 命名参数使用键值对格式
                args.append(f'("{kw_name}", {arg_code})')
            elif (
                hasattr(kw_tuple, "arg") and kw_tuple.arg and hasattr(kw_tuple, "value")
            ):
                # 备用处理方式，如果是对象形式
                arg_code = generator.generate_expression(
                    kw_tuple.value, context, parent_precedence=100
                )
                args.append(f'("{kw_tuple.arg}", {arg_code})')

    # 生成函数调用
    args_str = ", ".join(args)
    return f"{function_name}({args_str})"


@extension_processor(
    "mc_log_functions",
    match_rule=[{"node_type": "call"}],
    priority=100,  # 高优先级，确保在其他处理器之前执行
)
def process_mc_log_functions(context: IRContext):
    """处理 MC 日志函数调用，为其设置代码生成回调"""

    if context.node.node_type != "call":
        return

    call_node = cast(IRCall, context.node)
    func_name = call_node.get_func_name()
    if not func_name or func_name not in LOG_FUNCS:
        return

    call_node.set_emitter(_generate_log_code)


def _generate_log_code(node, generator, context) -> str:
    """日志代码生成"""
    func_name = node.get_func_name()
    if not func_name or func_name not in LOG_FUNCS:
        return "/* Invalid log function name */"

    return generate_log_code(node, func_name)
